package com.it.schoolbookshop_back.service.impl;

import com.it.schoolbookshop_back.entities.po.Book;
import com.it.schoolbookshop_back.entities.po.Category;
import com.it.schoolbookshop_back.entities.dto.BookResponseDTO;
import com.it.schoolbookshop_back.entities.dto.BookAddDTO;
import com.it.schoolbookshop_back.entities.dto.BookEditDTO;
import com.it.schoolbookshop_back.entities.dto.SoldBookDTO;
import com.it.schoolbookshop_back.enums.BookConditionEnum;
import com.it.schoolbookshop_back.enums.BookStatusEnum;
import com.it.schoolbookshop_back.enums.PriceRangeEnum;
import com.it.schoolbookshop_back.enums.SortByEnum;
import com.it.schoolbookshop_back.mapper.BookMapper;
import com.it.schoolbookshop_back.mapper.CategoryMapper;
import com.it.schoolbookshop_back.mapper.FavoriteMapper;
import com.it.schoolbookshop_back.mapper.UserMapper;
import com.it.schoolbookshop_back.service.BookService;
import com.it.schoolbookshop_back.service.CategoryService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.List;
import java.util.Base64;
import java.util.concurrent.TimeUnit;

/**
 * 书籍服务实现类
 */
@Service
public class BookServiceImpl implements BookService {
    
    private static final Logger log = LoggerFactory.getLogger(BookServiceImpl.class);
    
    private final BookMapper bookMapper;
    private final CategoryService categoryService;
    private final CategoryMapper categoryMapper;
    private final RedisTemplate<String, Object> redisTemplate;
    private final FavoriteMapper favoriteMapper;
    private final UserMapper userMapper;
    
    @Autowired
    public BookServiceImpl(BookMapper bookMapper, CategoryService categoryService, CategoryMapper categoryMapper, 
                           RedisTemplate<String, Object> redisTemplate, FavoriteMapper favoriteMapper,
                           UserMapper userMapper) {
        this.bookMapper = bookMapper;
        this.categoryService = categoryService;
        this.categoryMapper = categoryMapper;
        this.redisTemplate = redisTemplate;
        this.favoriteMapper = favoriteMapper;
        this.userMapper = userMapper;
    }
    
    @Override
    public List<Book> getBooks(PriceRangeEnum priceRange, BookConditionEnum bookCondition, SortByEnum sort) {
        // 处理价格区间
        BigDecimal minPrice = null;
        BigDecimal maxPrice = null;
        if (priceRange != null) {
            // 从枚举中获取价格区间
            switch (priceRange) {
                case BELOW_20:
                    minPrice = BigDecimal.ZERO; // 0元
                    maxPrice = new BigDecimal("20.0"); // 20元
                    break;
                case RANGE_20_50:
                    minPrice = new BigDecimal("20.0"); // 20元
                    maxPrice = new BigDecimal("50.0"); // 50元
                    break;
                case RANGE_50_100:
                    minPrice = new BigDecimal("50.0"); // 50元
                    maxPrice = new BigDecimal("100.0"); // 100元
                    break;
                case ABOVE_100:
                    minPrice = new BigDecimal("100.0"); // 100元以上
                    // maxPrice保持null，表示没有上限
                    break;
            }
        }
        
        // 处理书本品相 - 数据库中存储的是小写的：new, good, used
        String condition = null;
        if (bookCondition != null) {
            // 从枚举转换为数据库中的值
            switch (bookCondition) {
                case NEW:
                    condition = "new";
                    break;
                case GOOD:
                    condition = "good";
                    break;
                case USED:
                    condition = "used";
                    break;
            }
        }
        
        // 处理排序方式
        String orderBy = null;
        String sortDirection = null;
        if (sort != null) {
            switch (sort) {
                case PRICE_ASC:
                    orderBy = "price";
                    sortDirection = "asc";
                    break;
                case PRICE_DESC:
                    orderBy = "price";
                    sortDirection = "desc";
                    break;
                case CONDITION_PRIORITY:
                    orderBy = "condition";
                    break;
                case TIME_DESC:
                    // 默认按时间降序，不需要特殊处理
                    break;
            }
        }
        
        // 打印实际执行时的查询参数，便于调试
        System.out.println("\n====== 数据库查询开始 ======");
        System.out.println("原始参数: priceRange=" + priceRange + ", bookCondition=" + bookCondition + ", sort=" + sort);
        System.out.println("转换后参数: minPrice=" + minPrice + ", maxPrice=" + maxPrice + ", condition=" + condition + ", orderBy=" + orderBy + ", sortDirection=" + sortDirection);
        
        // 构造可能的查询SQL，便于调试
        StringBuilder sqlExample = new StringBuilder("SELECT * FROM books WHERE status='active'");
        if (minPrice != null) sqlExample.append(" AND price >= ").append(minPrice);
        if (maxPrice != null) sqlExample.append(" AND price <= ").append(maxPrice);
        if (condition != null) sqlExample.append(" AND book_condition='").append(condition).append("'");
        if (orderBy != null && sortDirection != null) {
            sqlExample.append(" ORDER BY ").append(orderBy).append(" ").append(sortDirection);
        } else {
            sqlExample.append(" ORDER BY created_at DESC");
        }
        System.out.println("模拟SQL: " + sqlExample.toString());
        
        // 执行查询并返回结果
        List<Book> books = bookMapper.getBooks(minPrice, maxPrice, condition, orderBy, sortDirection);
        System.out.println("查询结果数量: " + books.size());
        // 打印前几本书的基本信息，方便调试
        for (Book book : books) {
            System.out.println("书本: id=" + book.getId() + ", title=" + book.getTitle() + 
                            ", price=" + book.getPrice() + ", condition=" + book.getBookCondition());
        }
        System.out.println("====== 数据库查询结束 ======\n");
        
        return books;
    }

    @Override
    public List<BookResponseDTO> getBooksWithSeller(PriceRangeEnum priceRange, BookConditionEnum bookCondition, SortByEnum sort) {
        // 处理价格区间
        BigDecimal minPrice = null;
        BigDecimal maxPrice = null;
        if (priceRange != null) {
            // 从枚举中获取价格区间
            switch (priceRange) {
                case BELOW_20:
                    minPrice = BigDecimal.ZERO; // 0元
                    maxPrice = new BigDecimal("20.0"); // 20元
                    break;
                case RANGE_20_50:
                    minPrice = new BigDecimal("20.0"); // 20元
                    maxPrice = new BigDecimal("50.0"); // 50元
                    break;
                case RANGE_50_100:
                    minPrice = new BigDecimal("50.0"); // 50元
                    maxPrice = new BigDecimal("100.0"); // 100元
                    break;
                case ABOVE_100:
                    minPrice = new BigDecimal("100.0"); // 100元以上
                    // maxPrice保持null，表示没有上限
                    break;
            }
        }
        
        // 处理书本品相 - 数据库中存储的是小写的：new, good, used
        String condition = null;
        if (bookCondition != null) {
            // 从枚举转换为数据库中的值
            switch (bookCondition) {
                case NEW:
                    condition = "new";
                    break;
                case GOOD:
                    condition = "good";
                    break;
                case USED:
                    condition = "used";
                    break;
            }
        }
        
        // 处理排序方式
        String orderBy = null;
        String sortDirection = null;
        if (sort != null) {
            switch (sort) {
                case PRICE_ASC:
                    orderBy = "price";
                    sortDirection = "asc";
                    break;
                case PRICE_DESC:
                    orderBy = "price";
                    sortDirection = "desc";
                    break;
                case CONDITION_PRIORITY:
                    orderBy = "condition";
                    break;
                case TIME_DESC:
                    // 默认按时间降序，不需要特殊处理
                    break;
            }
        }
        
        // 打印实际执行时的查询参数，便于调试
        System.out.println("\n====== 联表查询开始 ======");
        System.out.println("原始参数: priceRange=" + priceRange + ", bookCondition=" + bookCondition + ", sort=" + sort);
        System.out.println("转换后参数: minPrice=" + minPrice + ", maxPrice=" + maxPrice + ", condition=" + condition + ", orderBy=" + orderBy + ", sortDirection=" + sortDirection);
        
        // 执行联表查询并返回结果
        List<BookResponseDTO> books = bookMapper.getBooksWithSeller(minPrice, maxPrice, condition, orderBy, sortDirection);
        System.out.println("查询结果数量: " + books.size());
        // 打印前几本书的基本信息，方便调试
        for (BookResponseDTO book : books) {
            System.out.println("书本: id=" + book.getId() + ", title=" + book.getTitle() + 
                            ", price=" + book.getPrice() + ", 品相=" + book.getBookCondition() +
                            ", 卖家=" + book.getSellerName() + ", 院系=" + book.getDepartment());
        }
        System.out.println("====== 联表查询结束 ======\n");
        
        return books;
    }

    @Override
    public List<Book> getBooksBySeller(Integer sellerId, String status) {
        System.out.println("\n====== 查询用户发布的书籍 ======");
        System.out.println("卖家ID: " + sellerId + ", 状态: " + (status != null ? status : "全部"));
        
        // 获取状态对应的枚举实例（用于日志记录）
        if (status != null && !status.isEmpty()) {
            BookStatusEnum statusEnum = BookStatusEnum.fromValue(status);
            if (statusEnum != null) {
                System.out.println("状态枚举: " + statusEnum.name() + ", 描述: " + statusEnum.getLabel());
            }
        }
        
        List<Book> books = bookMapper.getBooksBySeller(sellerId, status);
        
        System.out.println("查询结果数量: " + books.size());
        for (Book book : books) {
            System.out.println("- " + book.getId() + ": " + book.getTitle() + 
                              ", 价格: " + book.getPrice() + 
                              ", 状态: " + book.getStatus());
        }
        System.out.println("====== 查询用户发布的书籍结束 ======\n");
        
        return books;
    }

    @Override
    @Transactional
    public Integer addBook(BookAddDTO bookAddDTO, Integer sellerId) {
        if (bookAddDTO == null || sellerId == null) {
            return null;
        }
        
        // 验证数据
        if (bookAddDTO.getTitle() == null || bookAddDTO.getTitle().trim().isEmpty()) {
            throw new IllegalArgumentException("书名不能为空");
        }
        
        if (bookAddDTO.getAuthor() == null || bookAddDTO.getAuthor().trim().isEmpty()) {
            throw new IllegalArgumentException("作者不能为空");
        }
        
        if (bookAddDTO.getCategory() == null || bookAddDTO.getCategory().trim().isEmpty()) {
            throw new IllegalArgumentException("分类不能为空");
        }
        
        if (bookAddDTO.getPrice() == null || bookAddDTO.getPrice() < 0) {
            throw new IllegalArgumentException("价格必须大于等于0");
        }
        
        if (bookAddDTO.getNewDegree() == null || bookAddDTO.getNewDegree() < 0 || bookAddDTO.getNewDegree() > 100) {
            throw new IllegalArgumentException("新旧程度必须在0-100之间");
        }
        
        if (bookAddDTO.getDescription() == null || bookAddDTO.getDescription().trim().isEmpty()) {
            throw new IllegalArgumentException("描述不能为空");
        }
        
        // 处理分类，如果分类存在则使用现有分类ID，否则创建新分类
        Integer categoryId = null;
        
        // 查找是否存在该分类
        Category category = categoryMapper.findByName(bookAddDTO.getCategory());
        
        if (category != null) {
            // 分类已存在，使用其ID
            categoryId = category.getId();
        } else {
            // 创建新分类
            Category newCategory = new Category();
            newCategory.setName(bookAddDTO.getCategory());
            newCategory.setDescription("用户创建的分类: " + bookAddDTO.getCategory());
            
            Integer newCategoryId = categoryService.createCategory(newCategory);
            if (newCategoryId == null) {
                throw new RuntimeException("创建分类失败");
            }
            
            categoryId = newCategoryId;
        }
        
        // 根据新旧程度设置书籍状况
        String bookCondition;
        int newDegree = bookAddDTO.getNewDegree();
        
        // 更新判断逻辑：0-30为used，30-70为good，70-100为new
        if (newDegree >= 70) {
            bookCondition = "new"; // 几乎全新
        } else if (newDegree >= 30) {
            bookCondition = "good"; // 品相良好
        } else {
            bookCondition = "used"; // 有使用痕迹
        }
        
        System.out.println("根据新旧程度(" + newDegree + ")设置书籍品相为: " + bookCondition);
        
        // 如果已有设置的bookCondition，则使用传入的值
        if (bookAddDTO.getBookCondition() != null && !bookAddDTO.getBookCondition().isEmpty()) {
            bookCondition = bookAddDTO.getBookCondition();
            System.out.println("使用传入的书籍品相: " + bookCondition);
        }
        
        // 创建Book对象
        Book book = new Book();
        book.setTitle(bookAddDTO.getTitle());
        book.setAuthor(bookAddDTO.getAuthor());
        book.setCategoryId(categoryId);
        book.setPrice(BigDecimal.valueOf(bookAddDTO.getPrice()));
        book.setBookCondition(bookCondition);
        book.setNewDegree(bookAddDTO.getNewDegree());
        book.setDescription(bookAddDTO.getDescription());
        book.setSellerId(sellerId);
        book.setStatus("active"); // 默认设置为active状态
        book.setViews(0); // 设置初始浏览次数为0
        
        // 处理封面图片
        if (bookAddDTO.getCover() != null && bookAddDTO.getCoverType() != null) {
            try {
                // 将Base64字符串解码为字节数组
                byte[] coverBytes = Base64.getDecoder().decode(bookAddDTO.getCover());
                
                // 生成唯一文件名：书名_作者_毫秒时间戳.扩展名
                String timestamp = String.valueOf(System.currentTimeMillis());
                String fileName = book.getTitle().replaceAll("[\\\\/:*?\"<>|]", "_") + "_" 
                               + book.getAuthor().replaceAll("[\\\\/:*?\"<>|]", "_") + "_" 
                               + timestamp;
                
                // 根据图片类型添加正确的扩展名
                String extension = "";
                switch (bookAddDTO.getCoverType().toLowerCase()) {
                    case "image/jpeg":
                    case "image/jpg":
                        extension = ".jpg";
                        break;
                    case "image/png":
                        extension = ".png";
                        break;
                    case "image/gif":
                        extension = ".gif";
                        break;
                    case "image/webp":
                        extension = ".webp";
                        break;
                    default:
                        extension = ".jpg"; // 默认扩展名
                }
                
                fileName += extension;
                
                // 构建保存路径
                String imagePath = System.getProperty("user.dir") + "/src/main/resources/images/" + fileName;
                String relativePath = "images/" + fileName;
                
                // 确保目录存在
                java.io.File directory = new java.io.File(System.getProperty("user.dir") + "/src/main/resources/images/");
                if (!directory.exists()) {
                    directory.mkdirs();
                    System.out.println("创建目录: " + directory.getAbsolutePath());
                }
                
                // 将图片保存到文件系统
                java.nio.file.Path path = java.nio.file.Paths.get(imagePath);
                java.nio.file.Files.write(path, coverBytes);
                
                System.out.println("图片文件已保存到: " + path.toAbsolutePath());
                System.out.println("图片文件大小: " + coverBytes.length + " 字节");
                
                // 存储相对路径到数据库
                book.setCover(relativePath); // 直接存储路径字符串
                book.setCoverType(bookAddDTO.getCoverType());
                
                System.out.println("准备保存到数据库的封面路径: " + book.getCover());
                System.out.println("准备保存到数据库的封面类型: " + book.getCoverType());
                
                System.out.println("保存书籍封面到文件系统，路径: " + imagePath + 
                                  ", 类型: " + bookAddDTO.getCoverType() + 
                                  ", 大小: " + coverBytes.length + " 字节");
            } catch (Exception e) {
                System.err.println("处理封面图片时出错: " + e.getMessage());
                e.printStackTrace();
                // 如果保存失败，不设置封面
            }
        }
        
        // 保存书籍信息
        System.out.println("执行SQL前book对象信息: ID=" + book.getId() + 
                          ", 标题=" + book.getTitle() + 
                          ", 封面路径=" + book.getCover() +
                          ", 封面类型=" + book.getCoverType());
        
        int result = bookMapper.addBook(book);
        
        System.out.println("SQL执行结果: " + result + "，受影响行数");
        System.out.println("SQL执行后book对象信息: ID=" + book.getId() + 
                          ", 标题=" + book.getTitle() + 
                          ", 封面路径=" + book.getCover() +
                          ", 封面类型=" + book.getCoverType());
        
        System.out.println("添加书籍: " + book.getTitle() + ", ID: " + book.getId() + 
                          ", 分类: " + bookAddDTO.getCategory() + " (ID: " + categoryId + ")" +
                          ", 卖家ID: " + sellerId +
                          ", 是否有封面: " + (book.getCover() != null));
        
        // 增加用户的在售书籍数量
        if (result > 0) {
            try {
                userMapper.incrementBookCount(sellerId);
                log.info("用户ID: {} 的在售书籍数量已增加", sellerId);
            } catch (Exception e) {
                log.error("更新用户在售书籍数量失败: {}", e.getMessage(), e);
                // 不影响主流程
            }
        }
        
        return result > 0 ? book.getId() : null;
    }


    @Override
    public List<BookResponseDTO> getRecommendBooks(Integer bookId) {
        // 验证参数
        if (bookId == null) {
            throw new IllegalArgumentException("书籍ID不能为空");
        }
        
        // 先获取原书籍信息
        Book originalBook = bookMapper.getBookById(bookId);
        if (originalBook == null) {
            throw new IllegalArgumentException("书籍不存在");
        }
        
        // 默认最多返回6本推荐书籍
        final int MAX_RECOMMEND_COUNT = 6;
        
        System.out.println("\n====== 开始获取推荐书籍 ======");
        System.out.println("参考书籍: ID=" + originalBook.getId() + 
                          ", 标题=" + originalBook.getTitle() + 
                          ", 作者=" + originalBook.getAuthor() + 
                          ", 分类ID=" + originalBook.getCategoryId());
        
        // 根据原书籍的分类和作者查找类似的书籍
        List<BookResponseDTO> recommendBooks = bookMapper.getRecommendBooks(
            originalBook.getId(),
            originalBook.getCategoryId(),
            originalBook.getAuthor(),
            MAX_RECOMMEND_COUNT
        );
        
        System.out.println("找到推荐书籍数量: " + recommendBooks.size());
        // 打印推荐书籍的基本信息，方便调试
        int count = 0;
        for (BookResponseDTO book : recommendBooks) {
            count++;
            System.out.println(count + ". " + book.getTitle() + 
                              " (ID: " + book.getId() + 
                              ", 作者: " + book.getAuthor() + 
                              ", 分类ID: " + book.getCategoryId() + ")");
            
            if (book.getCategoryId().equals(originalBook.getCategoryId()) && 
                book.getAuthor().equals(originalBook.getAuthor())) {
                System.out.println("   匹配度: 高 (分类和作者都相同)");
            } else if (book.getCategoryId().equals(originalBook.getCategoryId())) {
                System.out.println("   匹配度: 中 (分类相同)");
            } else if (book.getAuthor().equals(originalBook.getAuthor())) {
                System.out.println("   匹配度: 中 (作者相同)");
            } else {
                System.out.println("   匹配度: 低");
            }
        }
        System.out.println("====== 获取推荐书籍结束 ======\n");
        
        return recommendBooks;
    }

    @Override
    public BookResponseDTO getBookDetailById(Integer bookId) {
        // 验证参数
        if (bookId == null) {
            throw new IllegalArgumentException("书籍ID不能为空");
        }
        
        System.out.println("\n====== 获取单本书籍详情 ======");
        System.out.println("书籍ID: " + bookId);
        
        // 调用Mapper获取书籍详情（包含卖家和分类信息）
        BookResponseDTO bookDetail = bookMapper.getBookDetailById(bookId);
        
        if (bookDetail == null) {
            System.out.println("书籍不存在: ID = " + bookId);
            throw new IllegalArgumentException("书籍不存在");
        }
        
        // 处理cover和cover_type字段，转换为布尔值
        boolean hasCover = bookDetail.getCover() != null && !bookDetail.getCover().isEmpty();
        boolean hasCoverType = bookDetail.getCoverType() != null && !bookDetail.getCoverType().isEmpty();
        
        // 如果是详情查询，需要将原路径保留
        if (bookDetail.getCover() != null && !bookDetail.getCover().isEmpty()) {
            // 由于接口文档要求返回Boolean，需要做特殊处理
            bookDetail.setCover("true");
        } else {
            bookDetail.setCover("false");
        }
        
        bookDetail.setCoverType(hasCoverType ? "true" : "false");
        
        System.out.println("获取到书籍: " + bookDetail.getTitle() + 
                         ", 作者: " + bookDetail.getAuthor() + 
                         ", 分类ID: " + bookDetail.getCategoryId() + 
                         ", 卖家: " + bookDetail.getSellerName() +
                         ", 是否有封面: " + hasCover);
        System.out.println("====== 获取单本书籍详情结束 ======\n");
        
        return bookDetail;
    }
    
    @Override
    public Book getBookById(Integer bookId) {
        // 验证参数
        if (bookId == null) {
            throw new IllegalArgumentException("书籍ID不能为空");
        }
        
        System.out.println("\n====== 获取单本书籍基础信息 ======");
        System.out.println("书籍ID: " + bookId);
        
        // 调用Mapper获取书籍基础信息
        Book book = bookMapper.getBookById(bookId);
        
        if (book == null) {
            System.out.println("书籍不存在: ID = " + bookId);
            return null;
        }
        
        System.out.println("获取到书籍: " + book.getTitle() + 
                         ", 作者: " + book.getAuthor() + 
                         ", 分类ID: " + book.getCategoryId() + 
                         ", 卖家ID: " + book.getSellerId());
        System.out.println("====== 获取单本书籍基础信息结束 ======\n");
        
        return book;
    }
    
    @Override
    public boolean updateBookStatus(Integer bookId, String status) {
        // 验证参数
        if (bookId == null) {
            throw new IllegalArgumentException("书籍ID不能为空");
        }
        
        if (status == null || status.isEmpty()) {
            throw new IllegalArgumentException("状态不能为空");
        }
        
        // 检查状态值是否有效
        if (!BookStatusEnum.isValid(status)) {
            throw new IllegalArgumentException("无效的状态值：" + status);
        }
        
        System.out.println("\n====== 更新书籍状态 ======");
        System.out.println("书籍ID: " + bookId + ", 新状态: " + status);
        
        // 先检查书籍是否存在
        Book book = bookMapper.getBookById(bookId);
        if (book == null) {
            System.out.println("书籍不存在: ID = " + bookId);
            return false;
        }
        
        // 获取原状态
        String originalStatus = book.getStatus();
        
        // 更新书籍状态
        book.setStatus(status);
        int result = bookMapper.updateBook(book);
        
        boolean success = result > 0;
        System.out.println("书籍状态更新" + (success ? "成功" : "失败") + ": ID = " + bookId + 
                          ", 从 " + originalStatus + " 更新为 " + status);
        
        // 如果书籍从active状态变为其他状态(如removed)，减少用户的在售书籍数量
        if (success && "active".equals(originalStatus) && !"active".equals(status)) {
            try {
                userMapper.decrementBookCount(book.getSellerId());
                log.info("用户ID: {} 的在售书籍数量已减少", book.getSellerId());
            } catch (Exception e) {
                log.error("更新用户在售书籍数量失败: {}", e.getMessage(), e);
                // 不影响主流程
            }
        }
        
        System.out.println("====== 更新书籍状态结束 ======\n");
        
        return success;
    }

    @Override
    public boolean incrementBookViews(Integer bookId, Integer userId) {
        // 参数验证
        if (bookId == null || userId == null) {
            throw new IllegalArgumentException("书籍ID和用户ID不能为空");
        }
        
        System.out.println("\n====== 增加书籍浏览次数 ======");
        System.out.println("书籍ID: " + bookId + ", 用户ID: " + userId);
        
        try {
            // 先检查书籍是否存在
            Book book = bookMapper.getBookById(bookId);
            if (book == null) {
                System.out.println("书籍不存在: ID = " + bookId);
                return false;
            }
            
            // 生成Redis缓存key，格式为: book_view:{userId}:{bookId}
            String cacheKey = "book_view:" + userId + ":" + bookId;
            
            // 检查缓存中是否已存在该key（说明用户10分钟内已经浏览过该书籍）
            Boolean hasKey = redisTemplate.hasKey(cacheKey);
            
            if (Boolean.TRUE.equals(hasKey)) {
                System.out.println("用户在缓存有效期内已浏览过该书籍，不增加浏览次数");
                // 用户已经浏览过，无需增加浏览次数
                return true;
            }
            
            // 用户未浏览过或缓存已过期，增加浏览次数并设置Redis缓存
            int result = bookMapper.incrementBookViews(bookId);
            
            if (result > 0) {
                // 增加浏览次数成功，设置缓存，有效期10分钟
                redisTemplate.opsForValue().set(cacheKey, 1, 600, TimeUnit.SECONDS);
                System.out.println("增加浏览次数成功，已设置10分钟缓存");
                return true;
            } else {
                System.out.println("增加浏览次数失败");
                return false;
            }
        } catch (Exception e) {
            System.err.println("增加浏览次数时发生异常: " + e.getMessage());
            e.printStackTrace();
            return false;
        } finally {
            System.out.println("====== 增加书籍浏览次数结束 ======\n");
        }
    }

    @Override
    @Transactional
    public boolean deleteBook(Integer bookId) {
        if (bookId == null) {
            log.warn("删除书籍失败: bookId 为空");
            return false;
        }
        
        log.info("开始删除书籍, ID: {}", bookId);
        try {
            // 1. 检查书籍是否存在
            Book book = bookMapper.getBookById(bookId);
            if (book == null) {
                log.warn("要删除的书籍不存在, ID: {}", bookId);
                return false;
            }
            
            // 2. 获取收藏该书籍的用户ID列表
            List<Integer> favoriteUserIds = favoriteMapper.getUsersByFavoriteBook(bookId);
            
            // 3. 删除该书籍的所有收藏记录
            if (favoriteUserIds != null && !favoriteUserIds.isEmpty()) {
                int deletedFavorites = favoriteMapper.deleteFavoritesByBookId(bookId);
                log.info("已删除书籍ID={}的{}条收藏记录", bookId, deletedFavorites);
                
                // 4. 更新所有用户的收藏计数
                for (Integer userId : favoriteUserIds) {
                    favoriteMapper.decreaseFavoriteCount(userId);
                }
            }
            
            // 5. 如果书籍是active状态，减少卖家的在售书籍数量
            if ("active".equals(book.getStatus())) {
                try {
                    userMapper.decrementBookCount(book.getSellerId());
                    log.info("用户ID: {} 的在售书籍数量已减少", book.getSellerId());
                } catch (Exception e) {
                    log.error("更新用户在售书籍数量失败: {}", e.getMessage(), e);
                    // 不影响主流程
                }
            }
            
            // 6. 删除书籍本身
            int result = bookMapper.deleteBook(bookId);
            boolean success = result > 0;
            
            if (success) {
                log.info("成功删除书籍: ID={}, 标题={}", bookId, book.getTitle());
            } else {
                log.warn("删除书籍失败: ID={}, 标题={}", bookId, book.getTitle());
            }
            
            return success;
        } catch (Exception e) {
            log.error("删除书籍时出错: ID={}, 错误: {}", bookId, e.getMessage(), e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean editBook(BookEditDTO bookEditDTO, Integer userId) {
        if (bookEditDTO == null || bookEditDTO.getBookId() == null || userId == null) {
            log.warn("编辑书籍失败: 无效的参数");
            return false;
        }
        
        log.info("开始编辑书籍, ID: {}, 操作用户ID: {}", bookEditDTO.getBookId(), userId);
        
        try {
            // 1. 检查书籍是否存在
            Book existingBook = bookMapper.getBookById(bookEditDTO.getBookId());
            if (existingBook == null) {
                log.warn("要编辑的书籍不存在, ID: {}", bookEditDTO.getBookId());
                return false;
            }
            
            // 2. 验证当前用户是否是书籍所有者
            if (!existingBook.getSellerId().equals(userId)) {
                log.warn("用户ID: {} 尝试编辑不属于他的书籍, 书籍ID: {}, 书籍所有者ID: {}", 
                        userId, bookEditDTO.getBookId(), existingBook.getSellerId());
                return false;
            }
            
            // 3. 根据DTO更新Book对象 - 只更新非空字段
            Book bookToUpdate = new Book();
            bookToUpdate.setId(bookEditDTO.getBookId());
            
            if (bookEditDTO.getTitle() != null && !bookEditDTO.getTitle().trim().isEmpty()) {
                bookToUpdate.setTitle(bookEditDTO.getTitle());
            }
            
            if (bookEditDTO.getAuthor() != null && !bookEditDTO.getAuthor().trim().isEmpty()) {
                bookToUpdate.setAuthor(bookEditDTO.getAuthor());
            }
            
            // 处理分类
            if (bookEditDTO.getCategory() != null && !bookEditDTO.getCategory().trim().isEmpty()) {
                // 查找是否存在该分类
                Category category = categoryMapper.findByName(bookEditDTO.getCategory());
                
                if (category != null) {
                    // 分类已存在，使用其ID
                    bookToUpdate.setCategoryId(category.getId());
                } else {
                    // 创建新分类
                    Category newCategory = new Category();
                    newCategory.setName(bookEditDTO.getCategory());
                    newCategory.setDescription("用户创建的分类: " + bookEditDTO.getCategory());
                    
                    Integer newCategoryId = categoryService.createCategory(newCategory);
                    if (newCategoryId == null) {
                        throw new RuntimeException("创建分类失败");
                    }
                    
                    bookToUpdate.setCategoryId(newCategoryId);
                }
            }
            
            if (bookEditDTO.getPrice() != null) {
                bookToUpdate.setPrice(BigDecimal.valueOf(bookEditDTO.getPrice()));
            }
            
            // 处理新旧程度和书籍状况
            if (bookEditDTO.getNewDegree() != null) {
                // 验证新旧程度范围
                if (bookEditDTO.getNewDegree() < 0 || bookEditDTO.getNewDegree() > 100) {
                    throw new IllegalArgumentException("新旧程度必须在0-100之间");
                }
                
                bookToUpdate.setNewDegree(bookEditDTO.getNewDegree());
                
                // 根据新旧程度自动设置书籍状况
                int newDegree = bookEditDTO.getNewDegree();
                String bookCondition;
                
                if (newDegree >= 90) {
                    bookCondition = "new"; // 全新
                } else if (newDegree >= 60) {
                    bookCondition = "good"; // 良好
                } else {
                    bookCondition = "used"; // 已使用
                }
                
                bookToUpdate.setBookCondition(bookCondition);
            } else if (bookEditDTO.getBookCondition() != null && !bookEditDTO.getBookCondition().trim().isEmpty()) {
                // 如果没有提供新旧程度，但提供了书籍状况，则直接使用
                bookToUpdate.setBookCondition(bookEditDTO.getBookCondition());
            }
            
            if (bookEditDTO.getDescription() != null) {
                bookToUpdate.setDescription(bookEditDTO.getDescription());
            }
            
            // 处理封面图片
            if (bookEditDTO.getCover() != null && !bookEditDTO.getCover().isEmpty() && 
                bookEditDTO.getCoverType() != null && !bookEditDTO.getCoverType().isEmpty()) {
                try {
                    // 将Base64字符串解码为字节数组
                    byte[] coverBytes = Base64.getDecoder().decode(bookEditDTO.getCover());
                    
                    // 生成唯一文件名：书名_作者_毫秒时间戳.扩展名
                    String title = bookEditDTO.getTitle() != null ? 
                                   bookEditDTO.getTitle() : existingBook.getTitle();
                    String author = bookEditDTO.getAuthor() != null ? 
                                    bookEditDTO.getAuthor() : existingBook.getAuthor();
                    
                    String timestamp = String.valueOf(System.currentTimeMillis());
                    String fileName = title.replaceAll("[\\\\/:*?\"<>|]", "_") + "_" 
                                   + author.replaceAll("[\\\\/:*?\"<>|]", "_") + "_" 
                                   + timestamp;
                    
                    // 根据图片类型添加正确的扩展名
                    String extension = "";
                    switch (bookEditDTO.getCoverType().toLowerCase()) {
                        case "image/jpeg":
                        case "image/jpg":
                            extension = ".jpg";
                            break;
                        case "image/png":
                            extension = ".png";
                            break;
                        case "image/gif":
                            extension = ".gif";
                            break;
                        case "image/webp":
                            extension = ".webp";
                            break;
                        default:
                            extension = ".jpg"; // 默认扩展名
                    }
                    
                    fileName += extension;
                    
                    // 构建保存路径
                    String imagePath = System.getProperty("user.dir") + "/src/main/resources/images/" + fileName;
                    String relativePath = "images/" + fileName;
                    
                    // 确保目录存在
                    java.io.File directory = new java.io.File(System.getProperty("user.dir") + "/src/main/resources/images/");
                    if (!directory.exists()) {
                        directory.mkdirs();
                        System.out.println("创建目录: " + directory.getAbsolutePath());
                    }
                    
                    // 将图片保存到文件系统
                    java.nio.file.Path path = java.nio.file.Paths.get(imagePath);
                    java.nio.file.Files.write(path, coverBytes);
                    
                    System.out.println("图片文件已保存到: " + path.toAbsolutePath());
                    System.out.println("图片文件大小: " + coverBytes.length + " 字节");
                    
                    // 存储相对路径到数据库
                    bookToUpdate.setCover(relativePath);
                    bookToUpdate.setCoverType(bookEditDTO.getCoverType());
                    
                    System.out.println("准备保存到数据库的封面路径: " + bookToUpdate.getCover());
                    System.out.println("准备保存到数据库的封面类型: " + bookToUpdate.getCoverType());
                    
                    log.info("更新书籍封面，保存到文件系统，路径: {}, 类型: {}, 大小: {} 字节", 
                            imagePath, bookEditDTO.getCoverType(), coverBytes.length);
                } catch (Exception e) {
                    log.error("处理封面图片时出错: {}", e.getMessage(), e);
                    // 如果图片处理失败，继续处理其他字段，不中断整个更新流程
                }
            }
            
            // 4. 执行更新操作
            System.out.println("SQL执行前bookToUpdate对象信息: ID=" + bookToUpdate.getId() + 
                              ", 封面路径=" + bookToUpdate.getCover() +
                              ", 封面类型=" + bookToUpdate.getCoverType());
            
            int result = bookMapper.updateBook(bookToUpdate);
            
            System.out.println("SQL执行结果: " + result + "，受影响行数");
            System.out.println("SQL执行后bookToUpdate对象信息: ID=" + bookToUpdate.getId() + 
                              ", 封面路径=" + bookToUpdate.getCover() +
                              ", 封面类型=" + bookToUpdate.getCoverType());
            
            boolean success = result > 0;
            
            if (success) {
                log.info("成功更新书籍: ID={}, 标题={}", bookEditDTO.getBookId(), 
                        bookEditDTO.getTitle() != null ? bookEditDTO.getTitle() : existingBook.getTitle());
            } else {
                log.warn("更新书籍失败: ID={}", bookEditDTO.getBookId());
            }
            
            return success;
        } catch (Exception e) {
            log.error("编辑书籍时出错: ID={}, 错误: {}", bookEditDTO.getBookId(), e.getMessage(), e);
            return false;
        }
    }

    @Override
    public List<SoldBookDTO> getSoldBooks(Integer sellerId) {
        // 验证参数
        if (sellerId == null) {
            throw new IllegalArgumentException("卖家ID不能为空");
        }
        
        log.info("查询用户ID为 {} 的已售出书籍", sellerId);
        
        // 调用mapper查询已售出书籍
        List<SoldBookDTO> soldBooks = bookMapper.getSoldBooks(sellerId);
        
        log.info("用户ID {} 已售出 {} 本书籍", sellerId, soldBooks.size());
        
        return soldBooks;
    }
    
    @Override
    public List<SoldBookDTO> getBoughtBooks(Integer buyerId) {
        // 验证参数
        if (buyerId == null) {
            throw new IllegalArgumentException("买家ID不能为空");
        }
        
        log.info("查询用户ID为 {} 的已购买书籍", buyerId);
        
        // 调用mapper查询已购买书籍
        List<SoldBookDTO> boughtBooks = bookMapper.getBoughtBooks(buyerId);
        
        log.info("用户ID {} 已购买 {} 本书籍", buyerId, boughtBooks.size());
        
        return boughtBooks;
    }
} 